package fr.imag.ufrima.ima.project.core;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;


public class Image {
	private Logger logger = Logger.getLogger(getClass().getName());

	private String name;
	private BufferedImage originalImage;
	private BufferedImage bi;
	private int w, h;
	private int[][][] tab;
	private boolean modified;

	public Image(String name) {
		this.name = name;
		this.load();
	}

	public void load() {
		try {
			bi = ImageIO.read(new File(this.name));
			originalImage = ImageIO.read(new File(this.name));
			w = bi.getWidth();
			h = bi.getHeight();
		} catch (IOException e) {
			logger.error(String.format("Image could not be readed: %s ", e.getMessage()));

		}
		this.constructBackingArray();
	}

	public void constructBackingArray() {
		int i, j;
		tab = new int[w][h][4];

		for (j = 0; j < this.h; j++) {
			for (i = 0; i < this.w; i++) {
				int rgb = bi.getRGB(i, j);
				tab[i][j][0] = ((rgb >> 24) & 0xFF); // alpha
				tab[i][j][1] = ((rgb >> 16) & 0xFF); // rouge
				tab[i][j][2] = ((rgb >> 8) & 0xFF); // vert
				tab[i][j][3] = (rgb & 0xFF); // bleu

			}
		}
	}	

	public boolean saveToFile(String fileName, String fileFormat) {
		boolean result = false;

		try {
			result = ImageIO.write(bi, fileFormat, new File(fileName));
			modified = false;
			this.name = fileName;
		} catch (IOException e) {
			logger.error(String.format("Image could not be saved: %s ", e.getMessage()));
		}
		if (!result) {
			logger.error(String.format("Image could not be saved. Current supported formats: %s",
					Arrays.toString(ImageIO.getWriterFormatNames())));
		}

		return result;
	}

	public void modifyWithImage(BufferedImage newImage) {
		bi = newImage;
		w = bi.getWidth();
		h = bi.getHeight();

		constructBackingArray();
		modified = true;
	}

	/*
	 * Make image to go back to the originally opened file
	 */
	public void revert() {
		this.modifyWithImage(originalImage);
		modified = false;
	}

	public void annuler() {
		w = this.originalImage.getWidth();
		h = this.originalImage.getHeight();
		BufferedImage bip = new BufferedImage(w, h, this.originalImage.getType());
		bip.setRGB(0, 0, w, h, originalImage.getRGB(0, 0, w, h, null, 0, w), 0, w);
		this.bi = bip;
		constructBackingArray();
		modified = true;
	}

	public void valider() {
		w = this.bi.getWidth();
		h = this.bi.getHeight();
		BufferedImage bip = new BufferedImage(w, h, this.bi.getType());
		bip.setRGB(0, 0, w, h, this.bi.getRGB(0, 0, w, h, null, 0, w), 0, w);
		this.originalImage = bip;
	}

	public void setBufferedImage(BufferedImage bi) {
		this.bi = bi;
	}

	public BufferedImage getBufferedImage() {
		return bi;
	}

	public int[][][] getTab() {
		return tab;
	}

	public int getWidth() {
		return w;
	}

	public int getHeight() {
		return h;
	}

	public boolean isModified() {
		return modified;
	}

	public String getName() {
		return name;
	}
}
